#ifndef CODE_LINES_BUILDER_H
#define CODE_LINES_BUILDER_H

#include <ostream>
#include <fstream>

#include "GOAL.h"
#include "CodeLines.h"
#include "Grammar.h"
#include "Interpreter.h"

namespace GOAL {
		class  Code_Lines_Builder : public Visitor 
		{
		public:
      Code_Lines_Builder(const Udm::Object& parent, 
        const std::string& target_dir = "source",
        const std::string & type = "C++");
			virtual ~Code_Lines_Builder();

			virtual void Visit_AccumulatorBase(const AccumulatorBase&);
      virtual void Visit_RhsElement(const Grammar::RhsElement&);
      virtual void Visit_LhsElement(const Grammar::LhsElement&);
      virtual void Visit_InputElement(const Grammar::InputElement&);
      virtual void Visit_AssignmentLine(const Grammar::Assignment&);
      virtual void Visit_FunctionCallLine(const Grammar::FunctionCallLine&);
      virtual void Visit_InputLine(const Grammar::InputLine&);
			virtual void Visit_KeyboardConnection(const KeyboardConnection&);
			virtual void Visit_VariableRef(const VariableRef&);
			virtual void Visit_Plus(const Plus&);
			virtual void Visit_Divide(const Divide&);
			virtual void Visit_Times(const Times&);
			virtual void Visit_Minus(const Minus&);
			virtual void Visit_Modulus(const Modulus&);
			virtual void Visit_Function(const Function&);
			virtual void Visit_FunctionCall(const FunctionCall&);
			virtual void Visit_Class(const Class&);
			virtual void Visit_Module(const Module&);
			virtual void Visit_CodeAdapter(const CodeAdapter&);
			virtual void Visit_ModuleAdapter(const ModuleAdapter&);
			virtual void Visit_ClassAdapter(const ClassAdapter&);
			virtual void Visit_Not(const Not&);
			virtual void Visit_ConditionsAdapter(const ConditionsAdapter&);
			virtual void Visit_Assignment(const Assignment&);
			virtual void Visit_File(const File&);
			virtual void Visit_Console(const Console&);
			virtual void Visit_Keyboard(const Keyboard&);
			virtual void Visit_AssignmentConnection(const AssignmentConnection&);
			virtual void Visit_Brackets(const Brackets&);
			virtual void Visit_IndexConnection(const IndexConnection&);
			virtual void Visit_NonModifyingConnection(const NonModifyingConnection&);
			virtual void Visit_For(const For&);
			virtual void Visit_While(const While&);
			virtual void Visit_If(const If&);
			virtual void Visit_PlusEquals(const PlusEquals&);
			virtual void Visit_DivideEquals(const DivideEquals&);
			virtual void Visit_MinusEquals(const MinusEquals&);
			virtual void Visit_TimesEquals(const TimesEquals&);
			virtual void Visit_Increment(const Increment&);
			virtual void Visit_Decrement(const Decrement&);
			virtual void Visit_And(const And&);
			virtual void Visit_Or(const Or&);
			virtual void Visit_OutputConnection(const OutputConnection&);
			virtual void Visit_CommonConnection(const CommonConnection&);
			virtual void Visit_ArrayAssignmentConnection(const ArrayAssignmentConnection&);
			virtual void Visit_AssignmentRHSConnection(const AssignmentRHSConnection&);
			virtual void Visit_ArgumentConnection(const ArgumentConnection&);
			virtual void Visit_Array(const Array&);
			virtual void Visit_Return(const Return&);
			virtual void Visit_Argument(const Argument&);
			virtual void Visit_Const(const Const&);
			virtual void Visit_ClassMember(const ClassMember&);
			virtual void Visit_ClassRef(const ClassRef&);
			virtual void Visit_Variable(const Variable&);
			virtual void Visit_RootFolder(const RootFolder&);
			virtual void Visit_Object(const Udm::Object&);

      // custom grammar types
      virtual void Visit_ConsolePrint(const GOAL::Grammar::ConsolePrint&);

      int get_num_lines ();
      Code_Lines & get_lines ();
    private:
      int tabs_;
      Code_Lines code_lines_;
      std::string target_dir_;
      std::string type_;
      GOAL::Grammar grammar_;
      GOAL::Interpreter interpreter_;
      std::ofstream header_;
      std::ofstream source_;
      std::map <std::string,bool> settings_;
		};
}

#endif // CODE_LINES_BUILDER_H